use core::{SourceMap, Package, PackageId, PackageSet, Resolve, Target};
use util::{mod, CargoResult, ChainError, internal, Config, profile, Require};
+use util::human;
use super::{Kind, KindPlugin, KindTarget, Compilation};
use super::layout::{Layout, LayoutProxy};
host: Layout,
target: Option<Layout>,
target_triple: String,
- host_dylib: (String, String),
+ host_triple: String,
+ host_dylib: Option<(String, String)>,
package_set: &'a PackageSet,
- target_dylib: (String, String),
+ target_dylib: Option<(String, String)>,
target_exe: String,
requirements: HashMap<(&'a PackageId, &'a str), PlatformRequirement>,
}
};
let (rustc_version, rustc_host) = try!(Context::rustc_version());
let target_triple = config.target().map(|s| s.to_string());
- let target_triple = target_triple.unwrap_or(rustc_host);
+ let target_triple = target_triple.unwrap_or(rustc_host.clone());
Ok(Context {
rustc_version: rustc_version,
target_triple: target_triple,
+ host_triple: rustc_host,
env: env,
host: host,
target: target,
/// Run `rustc` to discover the dylib prefix/suffix for the target
/// specified as well as the exe suffix
fn filename_parts(target: Option<&str>)
- -> CargoResult<((String, String), String)> {
+ -> CargoResult<(Option<(String, String)>, String)> {
let process = util::process("rustc")
.arg("-")
.arg("--crate-name").arg("-")
};
let output = try!(process.exec_with_output());
+ let error = str::from_utf8(output.error.as_slice()).unwrap();
let output = str::from_utf8(output.output.as_slice()).unwrap();
let mut lines = output.lines();
- let dylib_parts: Vec<&str> = lines.next().unwrap().trim()
- .split('-').collect();
- assert!(dylib_parts.len() == 2,
- "rustc --print-file-name output has changed");
+ let dylib = if error.contains("dropping unsupported crate type `dylib`") {
+ None
+ } else {
+ let dylib_parts: Vec<&str> = lines.next().unwrap().trim()
+ .split('-').collect();
+ assert!(dylib_parts.len() == 2,
+ "rustc --print-file-name output has changed");
+ Some((dylib_parts[0].to_string(), dylib_parts[1].to_string()))
+ };
+
let exe_suffix = lines.next().unwrap().trim()
.split('-').skip(1).next().unwrap().to_string();
-
- Ok(((dylib_parts[0].to_string(), dylib_parts[1].to_string()),
- exe_suffix.to_string()))
+ Ok((dylib, exe_suffix.to_string()))
}
/// Prepare this context, ensuring that all filesystem directories are in
///
/// If `plugin` is true, the pair corresponds to the host platform,
/// otherwise it corresponds to the target platform.
- fn dylib(&self, kind: Kind) -> (&str, &str) {
- let pair = if kind == KindPlugin {&self.host_dylib} else {&self.target_dylib};
- (pair.ref0().as_slice(), pair.ref1().as_slice())
+ fn dylib(&self, kind: Kind) -> CargoResult<(&str, &str)> {
+ let (triple, pair) = if kind == KindPlugin {
+ (&self.host_triple, &self.host_dylib)
+ } else {
+ (&self.target_triple, &self.target_dylib)
+ };
+ match *pair {
+ None => return Err(human(format!("dylib outputs are not supported \
+ for {}", triple))),
+ Some((ref s1, ref s2)) => Ok((s1.as_slice(), s2.as_slice())),
+ }
}
/// Return the target triple which this context is targeting.
}
/// Return the exact filename of the target.
- pub fn target_filenames(&self, target: &Target) -> Vec<String> {
+ pub fn target_filenames(&self, target: &Target) -> CargoResult<Vec<String>> {
let stem = target.file_stem();
let mut ret = Vec::new();
if target.is_dylib() {
let plugin = target.get_profile().is_plugin();
let kind = if plugin {KindPlugin} else {KindTarget};
- let (prefix, suffix) = self.dylib(kind);
+ let (prefix, suffix) = try!(self.dylib(kind));
ret.push(format!("{}{}{}", prefix, stem, suffix));
}
if target.is_rlib() {
}
}
assert!(ret.len() > 0);
- return ret;
+ return Ok(ret);
}
/// For a package, return all targets which are registered as dependencies
let (mut libs, mut bins) = (Vec::new(), Vec::new());
for &target in targets.iter() {
let work = if target.get_profile().is_doc() {
- vec![(rustdoc(pkg, target, cx), KindTarget)]
+ vec![(try!(rustdoc(pkg, target, cx)), KindTarget)]
} else {
let req = cx.get_requirement(pkg, target);
- rustc(pkg, target, cx, req)
+ try!(rustc(pkg, target, cx, req))
};
let dst = if target.is_lib() {&mut libs} else {&mut bins};
}
fn rustc(package: &Package, target: &Target,
- cx: &mut Context, req: PlatformRequirement) -> Vec<(Work, Kind)> {
+ cx: &mut Context, req: PlatformRequirement)
+ -> CargoResult<Vec<(Work, Kind)> >{
let crate_types = target.rustc_crate_types();
let root = package.get_root();
root.display(), target, crate_types, cx.primary, req);
let primary = cx.primary;
- let rustcs = prepare_rustc(package, target, crate_types, cx, req);
+ let rustcs = try!(prepare_rustc(package, target, crate_types, cx, req));
let _ = cx.config.shell().verbose(|shell| {
for &(ref rustc, _) in rustcs.iter() {
Ok(())
});
- rustcs.move_iter().map(|(rustc, kind)| {
+ Ok(rustcs.move_iter().map(|(rustc, kind)| {
let name = package.get_name().to_string();
(proc() {
}
Ok(())
}, kind)
- }).collect()
+ }).collect())
}
fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>,
cx: &Context, req: PlatformRequirement)
- -> Vec<(ProcessBuilder, Kind)> {
+ -> CargoResult<Vec<(ProcessBuilder, Kind)>> {
let base = process("rustc", package, cx);
let base = build_base_args(base, target, crate_types.as_slice());
let target_cmd = build_plugin_args(base.clone(), cx, package, target, KindTarget);
let plugin_cmd = build_plugin_args(base, cx, package, target, KindPlugin);
- let target_cmd = build_deps_args(target_cmd, target, package, cx, KindTarget);
- let plugin_cmd = build_deps_args(plugin_cmd, target, package, cx, KindPlugin);
+ let target_cmd = try!(build_deps_args(target_cmd, target, package, cx,
+ KindTarget));
+ let plugin_cmd = try!(build_deps_args(plugin_cmd, target, package, cx,
+ KindPlugin));
- match req {
+ Ok(match req {
Target => vec![(target_cmd, KindTarget)],
Plugin => vec![(plugin_cmd, KindPlugin)],
PluginAndTarget if cx.config.target().is_none() =>
vec![(target_cmd, KindTarget)],
PluginAndTarget => vec![(target_cmd, KindTarget),
(plugin_cmd, KindPlugin)],
- }
+ })
}
-fn rustdoc(package: &Package, target: &Target, cx: &mut Context) -> Work {
+fn rustdoc(package: &Package, target: &Target,
+ cx: &mut Context) -> CargoResult<Work> {
let kind = KindTarget;
let pkg_root = package.get_root();
let cx_root = cx.layout(kind).proxy().dest().join("doc");
let rustdoc = rustdoc.arg(target.get_src_path())
.arg("-o").arg(cx_root)
.arg("--crate-name").arg(target.get_name());
- let rustdoc = build_deps_args(rustdoc, target, package, cx, kind);
+ let rustdoc = try!(build_deps_args(rustdoc, target, package, cx, kind));
log!(5, "commands={}", rustdoc);
let primary = cx.primary;
let name = package.get_name().to_string();
- proc() {
+ Ok(proc() {
if primary {
try!(rustdoc.exec().chain_error(|| {
human(format!("Could not document `{}`.", name))
}))
}
Ok(())
- }
+ })
}
fn build_base_args(mut cmd: ProcessBuilder,
}
fn build_deps_args(mut cmd: ProcessBuilder, target: &Target, package: &Package,
- cx: &Context, kind: Kind) -> ProcessBuilder {
+ cx: &Context,
+ kind: Kind) -> CargoResult<ProcessBuilder> {
enum LinkReason { Dependency, LocalLib }
let layout = cx.layout(kind);
cmd = push_native_dirs(cmd, &layout, package, cx, &mut HashSet::new());
for &(_, target) in cx.dep_targets(package).iter() {
- cmd = link_to(cmd, target, cx, kind, Dependency);
+ cmd = try!(link_to(cmd, target, cx, kind, Dependency));
}
let mut targets = package.get_targets().iter().filter(|target| {
if target.is_bin() {
for target in targets {
- cmd = link_to(cmd, target, cx, kind, LocalLib);
+ cmd = try!(link_to(cmd, target, cx, kind, LocalLib));
}
}
- return cmd;
+ return Ok(cmd);
fn link_to(mut cmd: ProcessBuilder, target: &Target,
- cx: &Context, kind: Kind, reason: LinkReason) -> ProcessBuilder {
+ cx: &Context, kind: Kind,
+ reason: LinkReason) -> CargoResult<ProcessBuilder> {
// If this target is itself a plugin *or* if it's being linked to a
// plugin, then we want the plugin directory. Otherwise we want the
// target directory (hence the || here).
KindTarget => KindTarget,
});
- for filename in cx.target_filenames(target).iter() {
+ for filename in try!(cx.target_filenames(target)).iter() {
let mut v = Vec::new();
v.push_all(target.get_name().as_bytes());
v.push(b'=');
v.push_all(filename.as_bytes());
cmd = cmd.arg("--extern").arg(v.as_slice());
}
- return cmd;
+ return Ok(cmd);
}
fn push_native_dirs(mut cmd: ProcessBuilder, layout: &layout::LayoutProxy,